/**
 * Lockbox
 * a Password and Secret Information Manager
 * View to display a table of LockboxItems
 *
 * Created by Nathan Black
 */

#import <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <UIKit/UIBezierPath.h>
#import <UIKit/UIKeyboard.h>
#import <WebCore/WebFontCache.h>
#import "LockboxPwPromptView.h"
#import "LockboxTableCell.h"


@interface LockboxPwPromptView (Private)

- (void)passwordEntry:(NSString*)password;
- (void)enterPressed:( struct __GSEvent *)event;
- (UITextField*)createFieldWithTop:(float)top;

@end

@implementation LockboxPwPromptView

- (void)dealloc
{
    [_pwLabel release];
    [_pwField release];
    [_confirmLabel release];
    [_confirmField release];
    [_descLabel release];

    [super dealloc];
}

///////////// Constructor ////////////////
- (id)initWithFrame:(struct CGRect)frame promptState:(LockboxPwPromptState)state
{
    self = [super initWithFrame:frame];
    if (self)
    {
        //CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        _state = state;
        
        CGColorRef transp = [LockboxTableCell colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.0f];
        CGColorRef white = [LockboxTableCell colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f];
        [self setBackgroundColor:transp];
        
        _pwLabel = [[UITextLabel alloc] initWithFrame:CGRectMake(LBPP_MARGIN_X, 10.0f, LBPP_WIDTH - 40.0f, 25.0f)];
        if (state == LBPP_AUTH) {
            [_pwLabel setText:@"Enter Password"];
        }
        else {
            [_pwLabel setText:@"Enter New Password"];
        }
        [_pwLabel setCentersHorizontally:TRUE];
        [_pwLabel setBackgroundColor:transp];
        [_pwLabel setColor:white];
        
        _pwField = [self createFieldWithTop:40.0f];
        if (state == LBPP_AUTH) {
            [[_pwField textTraits] setReturnKeyType: 1 /* blue Go */];
            [_pwField setSecure:TRUE];
        }
        else {
            [[_pwField textTraits] setReturnKeyType: 4 /* next */];
        }
        [_pwField becomeFirstResponder /* set focus basically */];
        _focusField = _pwField;

        // Add a confirm field if we're changing the password, or setting it for the first time (should these be the same state?)
        if (state == LBPP_NEW || state == LBPP_CHANGE) {
            _confirmLabel = [[UITextLabel alloc] initWithFrame:CGRectMake(LBPP_MARGIN_X, 75.0f, LBPP_WIDTH - 40.0f, 27.0f)];
            [_confirmLabel setText:@"Confirm Password"];
            [_confirmLabel setCentersHorizontally:TRUE];
            [_confirmLabel setBackgroundColor:transp];
            [_confirmLabel setColor:white];
            
            _confirmField = [self createFieldWithTop:105.0f];
            [[_confirmField textTraits] setReturnKeyType: 1 /* blue Go */];
    
            // TODO: Add delete storage button
            [self addSubview:_confirmLabel];
            [self addSubview:_confirmField];
        }

        _descLabel = [[UITextLabel alloc] initWithFrame:CGRectMake(LBPP_MARGIN_X, frame.size.height - 28.0f, LBPP_WIDTH - (LBPP_MARGIN_X*2), 25.0f)];
        [_descLabel setText:@"Lockbox v0.5"];
        [_descLabel setCentersHorizontally:TRUE];
        [_descLabel setBackgroundColor:transp];
        [_descLabel setFont:[NSClassFromString(@"WebFontCache") createFontWithFamily:@"Helvetica" traits:0 size:14]];
        [_descLabel setColor:[LockboxTableCell colorWithRed:0.75f green:0.75f blue:0.75f alpha:1.0f]];

        [self addSubview:_descLabel];
        [self addSubview:_pwField];
        [self addSubview:_pwLabel];
        
        //CFRelease(colorSpace);
    }
    
    return self;
}

// consolidate common field options here
- (UITextField*)createFieldWithTop:(float) top
{
    UITextField* field = [[[UITextField alloc] initWithFrame:CGRectMake(LBPP_MARGIN_X, top, LBPP_WIDTH - 40.0f, 27.0f)] retain];
    [field setFont:[NSClassFromString(@"WebFontCache") createFontWithFamily:@"Helvetica" traits:0 size:18]];
    [field setBorderStyle:3];
    [field setPaddingTop:2.0f];
    [[field textTraits] setAutoCapsType: 0];
    [[field textTraits] setAutoCorrectionType: 1];
    [field setDelegate:self];
    [field addTarget:self action:@selector(enterPressed:) forEvents:0x80000 /* enter key */];
    return field;
}

- (void)setDelegate:(id)del
{
    // Delegate to send PasswordView notification that the return button was hit and to process the password.
    _delegate = del;
}

- (void)clearFields
{
    [_pwField setText:@""];
    if (_confirmField) [_confirmField setText:@""];
    [_pwField becomeFirstResponder];
}

- (void)alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button
{
    [sheet dismiss];
}

- (void)errorAlertUser:(NSString*)msg
{
    UIAlertSheet *infoSheet = [[UIAlertSheet alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
    [infoSheet setBodyText:msg];
    [infoSheet setTitle:@"Error"];
    [infoSheet addButtonWithTitle:@"OK"];
    [infoSheet setDelegate:self];
    [infoSheet setAlertSheetStyle:0];
    [infoSheet presentSheetFromAboveView:[self superview]];

}

- (void)textFieldDidBecomeFirstResponder:(id)field
{
    NSLog(@"DidBecomeFirstResponder: %@", field);
    _focusField = field;
}

- (void)setPwFieldFocus
{
    [_pwField becomeFirstResponder];
    _focusField = _pwField;
}

- (void)enterPressed:(struct __GSEvent *)event;
{
    // jump to the confirm field if changing or creating a new password, and the user hit enter on the first field
    if (_focusField == _pwField && (_state == LBPP_NEW || _state == LBPP_CHANGE)) {
        NSLog(@"setting focus");
        [_confirmField becomeFirstResponder];
        return;
    }
    
    // Input validation before password verification
    if ([_pwField text] == 0 || [[_pwField text] length] == 0) {
        [self errorAlertUser:@"You need to enter a password."];
    }
    else if ((_state == LBPP_NEW || _state == LBPP_CHANGE) && ([_confirmField text] == 0 || [[_confirmField text] length] == 0)) {
        [self errorAlertUser:@"You need to confirm your password."];
    }
    else if ((_state == LBPP_NEW || _state == LBPP_CHANGE) && [[_pwField text] length] < 6) {
        [self errorAlertUser:@"You need at least 6 characters in your password. Using non-dictionary words and including numbers is recommended."];
    }
    else if ((_state == LBPP_NEW || _state == LBPP_CHANGE) && ([[_pwField text] compare:[_confirmField text]] != NSOrderedSame)) {
        [self errorAlertUser:@"Your passwords do not match."];
        [_confirmField setText:@""];
    }
    else if (_delegate && [_delegate respondsToSelector:@selector(passwordEntry:)])
    {
        [_delegate passwordEntry:[_pwField text]];
        return;
    }
    
    // the first responder seems to be resigned by the text filed when we handle this event. maybe this event takes a return type back?
    [_pwField becomeFirstResponder];
}


- (void)drawRect:(struct CGRect)rect
{
    CGColorRef white25 = [LockboxTableCell colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.25f];
    CGColorRef black70 = [LockboxTableCell colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.70f];

    CGContextSetStrokeColorWithColor(UICurrentContext(), white25);
    CGContextSetFillColorWithColor(UICurrentContext(), black70);
    
    UIBezierPath *path;

    // fill the entire rect
    path = [UIBezierPath roundedRectBezierPath:rect withRoundedCorners:kUIBezierPathAllCorners withCornerRadius:20.0];
    [path fill];
    
    // stroke an inset and rounded rect
    struct CGRect innerRect = CGRectInset(rect, 1.0, 1.0);
    path = [UIBezierPath roundedRectBezierPath:innerRect withRoundedCorners:kUIBezierPathAllCorners withCornerRadius:20.0];
    [path setLineWidth:2.0f];
    [path stroke];

    [super drawRect:rect];
}


/*- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
     NSLog(@"LBPwPromptView: Requested method for selector: %@", NSStringFromSelector(selector));
     return [super methodSignatureForSelector:selector];
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    NSLog(@"LBPwPromptView: Request for selector: %@", NSStringFromSelector(aSelector));
    return [super respondsToSelector:aSelector];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation {
     NSLog(@"LBPwPromptView: Called from: %@", NSStringFromSelector([anInvocation selector]));
    [super forwardInvocation:anInvocation];
}*/

@end
